import { Injectable, Logger, UnauthorizedException } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as jwt from 'jsonwebtoken';

@Injectable()
export class TokenService {
  private readonly logger = new Logger(TokenService.name);
  // eorder-server的默认JWT密钥
  private readonly EORDER_JWT_SECRET = 'hard!to-guess_secret';

  constructor(private configService: ConfigService) {}

  /**
   * 验证token
   * @param token JWT token
   * @returns 解析后的token payload或null（如果无效）
   */
  verifyToken(token: string): any {
    try {
      // 尝试使用配置的JWT密钥验证
      const jwtSecret = this.configService.get<string>('JWT_SECRET');
      
      // 如果配置了JWT_SECRET，尝试验证签名
      if (jwtSecret) {
        try {
          return jwt.verify(token, jwtSecret);
        } catch (error) {
          this.logger.warn(`JWT verification with local secret failed: ${error.message}`);
          // 如果本地验证失败，尝试使用eorder-server的默认密钥
          try {
            // 使用eorder-server的默认密钥
            return jwt.verify(token, this.EORDER_JWT_SECRET);
          } catch (eorderError) {
            this.logger.warn(`JWT verification with eorder secret failed: ${eorderError.message}`);
          }
        }
      } else {
        // 如果没有配置本地JWT_SECRET，直接尝试使用eorder-server的密钥
        try {
          return jwt.verify(token, this.EORDER_JWT_SECRET);
        } catch (error) {
          this.logger.warn(`JWT verification with eorder secret failed: ${error.message}`);
        }
      }
      
      // 如果验证都失败，则假设token是由主应用签发的
      // 在这种情况下，我们只解码token而不验证签名
      this.logger.warn('JWT verification failed, decoding token without verification');
      const decoded = jwt.decode(token);
      
      // 记录解码后的payload，用于调试
      this.logger.debug(`Decoded token payload: ${JSON.stringify(decoded)}`);
      
      return decoded;
    } catch (error) {
      this.logger.error(`Token verification failed: ${error.message}`);
      return null;
    }
  }

  /**
   * 从请求中提取token
   * @param request Express请求对象
   * @returns 提取的token或null
   */
  extractTokenFromHeader(request: any): string | null {
    const authHeader = request.headers.authorization;
    if (!authHeader) return null;
    
    const [type, token] = authHeader.split(' ');
    return type === 'Bearer' ? token : null;
  }

  /**
   * 检查用户是否具有指定角色
   * @param token JWT token
   * @param requiredRoles 需要的角色列表
   * @returns 是否具有所需角色
   */
  checkRoles(token: string, requiredRoles: string[]): boolean {
    const payload = this.verifyToken(token);
    
    if (!payload) {
      return false;
    }

    // 检查payload中的角色字段 - 支持多种可能的字段名
    let userRoles: string[] = [];
    
    // 检查常见的角色字段
    if (payload.roles && Array.isArray(payload.roles)) {
      userRoles = payload.roles;
    } else if (payload.roleCodes && Array.isArray(payload.roleCodes)) {
      // eorder-server使用roleCodes字段
      userRoles = payload.roleCodes;
    } else if (typeof payload.roles === 'string') {
      // 有些系统可能将角色存储为逗号分隔的字符串
      userRoles = payload.roles.split(',').map(role => role.trim());
    }

    if (userRoles.length === 0) {
      this.logger.warn(`Token payload does not contain valid roles: ${JSON.stringify(payload)}`);
      return false;
    }

    // 将所有角色名转换为小写进行比较
    const lowerCaseUserRoles = userRoles.map(role => role.toLowerCase());
    const lowerCaseRequiredRoles = requiredRoles.map(role => role.toLowerCase());

    // 检查用户是否拥有任一所需角色（不区分大小写）
    const hasRequiredRole = lowerCaseRequiredRoles.some(requiredRole => 
      lowerCaseUserRoles.includes(requiredRole)
    );

    if (!hasRequiredRole) {
      this.logger.warn(`User does not have any of the required roles. User roles: ${userRoles.join(', ')}, Required roles: ${requiredRoles.join(', ')}`);
    } else {
      this.logger.log(`User has required role. User roles: ${userRoles.join(', ')}, Required roles: ${requiredRoles.join(', ')}`);
    }

    return hasRequiredRole;
  }

  /**
   * 获取用户角色
   * @param token JWT token
   * @returns 用户角色数组
   */
  getUserRoles(token: string): string[] {
    const payload = this.verifyToken(token);
    
    if (!payload) {
      return [];
    }
    
    // 支持多种可能的角色字段名
    if (payload.roles && Array.isArray(payload.roles)) {
      return payload.roles;
    } else if (payload.roleCodes && Array.isArray(payload.roleCodes)) {
      // eorder-server使用roleCodes字段
      return payload.roleCodes;
    } else if (typeof payload.roles === 'string') {
      // 有些系统可能将角色存储为逗号分隔的字符串
      return payload.roles.split(',').map(role => role.trim());
    }
    
    return [];
  }

  /**
   * 获取用户ID
   * @param token JWT token
   * @returns 用户ID
   */
  getUserId(token: string): string | null {
    const payload = this.verifyToken(token);
    
    if (!payload) {
      return null;
    }

    // 尝试从不同的字段获取用户ID
    return payload.sub || payload.userId || payload.id || null;
  }
} 